home *** CD-ROM | disk | FTP | other *** search
- { Menu Generator
-
- Author: Michael H. Hughes; Hereby placed in the Public Domain
-
- This program illustrates the function "menu" which generates a very nice
- kind of menu display. This general type of menu has been common on Wang
- equipment for years, but has not caught on elsewhere. It is a neater and
- quicker menu than most of the common types.
-
- Pass the function a list of descriptive lines, and it will display them
- on the screen along with a heading and instructions. A pointer is displayed
- beside the first line of the list, and that line is highlighted. Press
- a key (usually the space-bar) and the pointer will drop one line down the
- list. Another key (backspace) will move the pointer back up the list.
- Pressing any character key will cause the routine to search for a line
- beginning with that character. If found, the pointer will be positioned
- on that line. Another key (return/enter) will cause the routine to exit
- and return the number of the selected line. Another key (ESC) can be used
- as a "cancel" and will return a zero.
-
- Up to 40 items can be displayed. The routine will position them
- automatically, using two columns if necessary.
-
- The routine requires a single-keystroke input routine which does not echo
- to the screen or require a return/enter to respond. A function suitable
- for MSDOS/PCDOS machines is supplied.
-
- The display will look better if you insert the necessary code to turn the
- cursor off.
-
- Note the use of a typeless parameter and an absolute address to pass an
- array of uknown length to the routine. }
-
-
-
-
-
-
- Function menu(number: Integer; Var data): Integer; { Generate Menu Display }
-
- Const llen = 80; { screen line length }
- slen = 20; { maximum number items in one column }
- maxnumber = 40; { maximum size of list array }
-
- movedownlist = 32; { SPACE key }
- moveuplist = 8; { BACKSPACE key }
- select = 13; { ENTER/RETURN key }
- cancel = 27; { ESC key }
-
- Type listtype=Array[0..maxnumber] Of String[30];
-
- Var list: listtype Absolute data;
- posn, len, margin, vmargin, maxlen: Integer;
- minlen, count, cnumber: Integer;
- ch: Char;
- chval: Byte;
-
- Function keyin: Byte; { Single-Key Input Routine (MSDOS/PCDOS) }
- Var register: Record { register pack }
- AX,BX,CX,DX,BP,SI,DI,DS,ES,FLAG: Integer;
- End;
-
- Begin
- register.AX := $0700; { call function 07 }
- MsDos(register);
- keyin := register.AX And $00FF;
- End;
-
-
- Begin { Menu }
- { Display Heading }
- ClrScr; LowVideo;
- write(chr(27),'[5h'); { ANSI cursor-off command; change as required }
- writeln(list[0]); { Title line }
- For posn:=1 To llen Do write('='); writeln;
-
- { Compute positioning parameters }
- If number > maxnumber Then number:=maxnumber;
- If number <= slen Then len:=number Else len:=slen;
- If number > slen Then margin:=1
- Else
- Begin
- maxlen:=0; minlen:=80;
- For count:=1 to number Do
- Begin
- If length(list[count]) > maxlen Then maxlen:=length(list[count]);
- If length(list[count]) < minlen Then minlen:=length(list[count])
- End;
- margin:=34-(maxlen+minlen) Div 4
- End;
- If number <= slen Then vmargin:=(slen-number) Div 2
- Else vmargin:=(slen-(number Div 2)) Div 2;
- vmargin:=vmargin+3;
- If number > slen Then
- Begin
- cnumber:=number Div 2;
- If odd(number) Then cnumber:=cnumber+1
- End
- Else cnumber:=number;
-
- { Display list }
- For posn:=1 To cnumber Do
- Begin
- gotoxy(margin+4,posn+vmargin);
- write(list[posn]);
- If ((number) > slen) And ((posn+cnumber) <= number) Then
- Begin
- gotoxy(45,posn+vmargin);
- write(list[posn+cnumber])
- End;
- writeln
- End;
-
- { Display Instructions }
- gotoxy(1,24); NormVideo;
- writeln('Press SPACE or BACKSPACE or First Letter of Line to Select');
- write('Press RETURN or ENTER to run your choice');
-
- { Pick menu }
- posn:=1;
- Repeat
- { Display current pick }
- gotoxy(((posn-1) Div cnumber)*40+margin,
- ((posn-1) Mod cnumber)+1+vmargin);
- NormVideo;
- write(' -> ',list[posn]);
- { Get Keyboard and clear current pick }
- chval:=keyin;
- gotoxy(((posn-1) Div cnumber)*40+margin,
- ((posn-1) Mod cnumber)+1+vmargin);
- LowVideo;
- If chval <> select Then write(' ',list[posn]);
-
- { Determine new Pick }
- If chval = select Then menu:=posn
- Else If chval = cancel Then menu:=0
- Else If chval = moveuplist Then
- If posn > 1 Then posn:=posn-1
- Else posn:=number
- Else If chval = movedownlist Then
- If posn < (number) Then posn:=posn+1
- Else posn:=1
- Else { Check for first character of line }
- Begin
- count:=posn;
- ch:=UpCase(chr(chval));
- Repeat
- count:=succ(count);
- If count > number Then count:=1
- Until (count = posn) Or (ch = UpCase(copy(list[count],1,1)));
- posn:=count
- End
- Until (chval = select) Or (chval = cancel)
- End;
-
-
-
- { The following program illustrates the use of MENU as a basic program loader.
- The typed constants are used to set up the menu, and can be changed to
- provide any desired choice. The program list is simply in the same order as
- the descriptive lines. Lines[0] defines the menu heading while progs[0] is
- the program to be loaded if the "cancel" key is pressed. }
-
-
- Const maxlines = 4; { number of lines in menu }
-
- lines: Array[0..maxlines] Of String[30] =
- ('General Business Menu',
- 'Accounts Receivable',
- 'Accounts Payable',
- 'Payroll',
- 'General Ledger');
-
- progs: Array[0..maxlines] Of String[30] = { list of programs to load }
- ('MAINMENU.COM',
- 'AR.COM',
- 'AP.COM',
- 'PA.COM',
- 'GL.COM');
-
- Var nextprog: File;
-
- Begin { Main Program }
- assign(nextprog,progs[menu(maxlines,lines)]);
- execute(nextprog)
- End.
-
-